package cn.wolfcode.rbac.service.impl;

import cn.wolfcode.rbac.domain.Employee;
import cn.wolfcode.rbac.mapper.EmployeeMapper;
import cn.wolfcode.rbac.mapper.PermissionMapper;
import cn.wolfcode.rbac.service.ILoginService;
import cn.wolfcode.rbac.springSecurity.detail.MyUserDetails;
import cn.wolfcode.rbac.utils.JwtUtils;
import cn.wolfcode.rbac.utils.RedisUtils;
import cn.wolfcode.rbac.utils.VerifyCodeUtil;
import cn.wolfcode.rbac.web.exception.BusinessException;
import cn.wolfcode.rbac.web.vo.LoginInfoVo;
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.UUID;

import static cn.wolfcode.rbac.common.RedisKeyPrefix.*;

@Service
@Transactional
public class LoginServiceImpl implements ILoginService{

    @Autowired
    private RedisUtils redisUtils;
//    @Autowired
//    private EmployeeMapper employeeMapper;
//    @Autowired
//    private PermissionMapper permissionMapper;
    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private JwtUtils jwtUtils;

    @Override
    public Map<String, String> generator() {
        //动态生成验证码图片
        Map<String, String> map = VerifyCodeUtil.generateVerifyCode();
        String code = map.get("code");
        System.out.println("code = " + code);
        String uuid = map.get("uuid");
        //给验证码设置过期时间
        redisUtils.set(VERIFY_CODE_PREFIX+uuid,code,EXPRE_TIME);
        //删除验证码
        map.remove("code");
        //返回验证码图片
        return map;
    }

    @Override
    public void logout(String token) {
            //解析uuid
        String uuid = jwtUtils.getPayload(token,"uuid");
        //根据uuid，从redis中删除员工信息和权限
            //1.删除redis中的员工信息
            redisUtils.del(LOGIN_EMPLOYEE_PREFIX+uuid);

            //2.删除redis中的员工信息的所有权限
//        redisUtils.del(EMPLOYEE_EXPRESSION_PREFIX+id);
    }

    @Override
    public String login(LoginInfoVo loginInfoVo) {
        //1.校验验证码
        String code = loginInfoVo.getCode();
        //获取redis的code进行校验
        String redisCode = redisUtils.get(VERIFY_CODE_PREFIX + loginInfoVo.getUuid());
        if(redisCode == null){
            //验证码过期,请重新获取
            throw new BusinessException("验证码过期,请重新获取");
        }
        if (!VerifyCodeUtil.verification(redisCode,code,true)) {
            throw new BusinessException("验证码不正确");
        }

        //2.从数据库中取出进行校验
        //校验用户名
        //校验密码
//        Employee employeeInfo = new Employee();
//        employeeInfo.setName(loginInfoVo.getUsername());
//        employeeInfo.setPassword(loginInfoVo.getPassword());
//        Employee employee = employeeMapper.selectByEmployeeInfo(employeeInfo);
//        if(employee == null){
//            throw new BusinessException("用户名和密码不正确");
//        }

        //用SpringSecurity的方式进行认证
        //1.把账号和密码封装到token中
        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(loginInfoVo.getUsername(),loginInfoVo.getPassword());
        //2.调用认证器进行认证
        Authentication authenticate = authenticationManager.authenticate(token);
        //3.通过认证器认证后获取用户对象
        Object principal = authenticate.getPrincipal();
        MyUserDetails myUserDetails = (MyUserDetails) principal;
        Employee employee = myUserDetails.getEmployee();
        //4.生成uuid
        String uuid = UUID.randomUUID().toString();
        //5.生成LoginToken,把uuid封装到token中
        String loginToken = jwtUtils.createTokenByPayloadString("uuid", uuid);


        //登录成功从redis中删除code验证码
        redisUtils.del(VERIFY_CODE_PREFIX + loginInfoVo.getUuid());
        //3.校验成功，employee信息存入redis中，用于权限校验时，从redis中获取是否登录
        //对employee进行序列化操作
        redisUtils.set(LOGIN_EMPLOYEE_PREFIX+uuid,JSON.toJSONString(employee));

        //4.再把该用户的权限也存入redis中，待下次访问时候，从redis中获取判断是否有权限
        //根据员工id查询所有的权限
//        Long employeeId = employee.getId();
//        List<String> expressions = permissionMapper.queryExpressionByEmployeeId(employeeId);
//
//        //如果有权限就保存到redis中
//        if(!expressions.isEmpty()){
//            redisUtils.set(EMPLOYEE_EXPRESSION_PREFIX+employeeId,JSON.toJSONString(expressions));
//        }

        return loginToken;
    }


}
